<?php

/**
 * @classname 排队
 * @classaccess public
 * @decription 排队接口
 * @author 张旭刚
 * @updateTime 2020年06月22日
 */

namespace api\controllers;

use Yii;
use api\models\Queues;

class QueuesController extends PublicController {

    private $limitTime; //超时时长
    private $waitTime; //每次执行等待时长
    private $curWait;

    public function __construct($id, $module, $config = array()) {
        parent::__construct($id, $module, $config);
        $this->limitTime = 100;
        $this->waitTime = 1;
        $this->curWait = 0;
    }


    /**
     * @see 立即排队
     * @describe 立即排队
     * @access public
     * @name que
     * @method POST
     * @requestType FORM
     * @defget no
     * @author 张旭刚,2020年6月22日,创建
     * 
     * @header guid|string|required|客户端唯一编号
     * @header token|string|required|用户登录证书
     * 
     * @return result|boolean|成功/失败（true/false）
     */
    public function actionQue() {
        $model = Queues::findOne(['memberKey' => $this->memberKey, 'inData' => date('Y-m-d'), 'status' => 1]);
        if(!empty($model)){
            return $this->renderJson(['code' => 1, 'msg' => '您的排队正在等待叫号，请耐心等待', 'result' => false, 'errorCode' => 104002]);
        }
        $m = new Queues();
        $m->queueNumber = $this->getQueueNumber();
        $queueNo = $this->getQueueNo($m->queueNumber);
        $baseStr = $this->memberKey.'_'.microtime().'_'.rand(100000, 999999).'_'.$queueNo;
        $salt = $this->setting('queue_key_salt');
        $m->queueKey = $this->sha256($baseStr, $salt);
        $m->memberKey = $this->memberKey;
        $m->inData = date('Y-m-d');
        if(!$queueNo){
            return $this->renderJson(['code' => 0, 'msg' => '排队序号容量不足，请重新设置排队序号容量', 'result' => false, 'errorCode' => 104003]);
        }
        $m->queueNo = $queueNo;
        $m->status = 1;
        $m->call = 1;
        $m->ctime = time();
        if($m->save(false)){
            return $this->renderJson(['code' => 1, 'msg' => '排队成功', 'result' => true, 'errorCode' => 0]);
        }
        return $this->renderJson(['code' => 0, 'msg' => '排队失败', 'result' => false, 'errorCode' => 104001]);
    }

    /**
     * @see 我的排队
     * @describe 我的排队
     * @access public
     * @name my-que
     * @method POST
     * @requestType FORM
     * @defget no
     * @author 张旭刚,2020年6月22日,创建
     * 
     * @header guid|string|required|客户端唯一编号
     * @header token|string|required|用户登录证书
     * 
     * @param status|string|required|当前使用状态
     * @param call|string|required|当前叫号状态
     * 
     * @return queueNo|boolean|排队序号
     * @return queueKey|boolean|排队唯一标识
     * @return call|boolean|叫号状态
     * @return status|boolean|排队状态
     * @return forwardTotal|boolean|前方人数
     * @return long|boolean|还需要多久
     */
    public function actionMyQue(){
        $status = intval(Yii::$app->request->post('status'));
        $call = intval(Yii::$app->request->post('call'));
        $result = $this->myQue($status, $call);
        return $this->renderJson(['code' => 1, 'msg' => '查询成功', 'result' => $result, 'errorCode' => 0]);
    }

    private function myQue($status, $call){
        if($this->curWait > $this->limitTime){
            return $this->renderJson(['code' => 0, 'msg' => '执行超时', 'result' => false, 'errorCode' => 104005]);
        }
        $m = Queues::find()->where(['memberKey' => $this->memberKey, 'inData' => date('Y-m-d'), 'status' => 1])->orderBy('queueNumber DESC')->one();
        if(empty($m)){
            return false;
        }
        if(!empty($status) || !empty($call)){
            if($status == $m->status && $call == $m->call){
                sleep($this->waitTime);
                $this->curWait += $this->waitTime;
                return $this->myQue($status, $call);
            }
        }
        $total = Queues::getForwardTotal($m->queueNumber);
        $long = $this->getWaitingLong($total);
        return ['queueKey' => $m->queueKey, 'queueNo' => $m->queueNo, 'call' => $m->call, 'status' => $m->status, 'forwardTotal' => $total, 'long' => $long];
    }

    /**
     * 计算等待时长
     */
    private function getWaitingLong($total){
        $speed = $this->setting('out_shop_speed');
        $second = $total * $speed;//秒
        $minitus = 0;
        $hour = 0;
        $day = 0;
        if($second > 60){
            $minitus = floor($second  /60);
            $second = $second % 60;
        }

        if($minitus > 60){
            $hour = floor($minitus  /60);
            $minitus = $minitus % 60;
        }

        if($hour > 24){
            $day = floor($hour  /24);
            $hour = $hour % 24;
        }

        $long = '';
        if(!empty($day)){
            $long .= $day.'天';
        }
        if(!empty($hour)){
            $long .= $hour.'小时';
        }
        if(!empty($minitus)){
            $long .= $minitus.'分钟';
        }
        if(!empty($second)){
            $long .= $second.'秒';
        }
        if(empty($long)){
            $long = '0秒';
        }
        return $long;
    }

    /**
     * 取得排队机读序号
     */
    private function getQueueNumber(){
        $cacheKey = 'queue_number_last';
        $c = $this->redis->hget($cacheKey, date('Y-m-d'));
        $number = empty($c) ? 1 : $c + 1;
        $this->redis->hset($cacheKey, date('Y-m-d'), $number);
        return $number;
    }
    
    /**
     * 取得排队认读序号
     */
    private function getQueueNo($queueNumber){
        $format = intval($this->setting('queue_no_format'));
        $prefix = $this->setting('queue_no_prefix');
        if(strlen($format) <= strlen($queueNumber)){
            $cacheKey = 'queue_number_last';
            $c = $this->redis->hget($cacheKey, date('Y-m-d'));
            $this->redis->hset($cacheKey, date('Y-m-d'), $c - 1);
            return false;
        }
        return $prefix.($format + $queueNumber);
    }


}
